package dmxGroupControl;

import dmxGroupControl.solvers.SimpleChaseSolver;
import dmxGroupControl.solvers.Solver;

import java.util.ArrayList;
import java.util.TreeSet;
import java.util.stream.Collectors;

public class Group
{
    TreeSet<Fixture> fixtures;
    String name;
    ArrayList<Solver> solvers;

    public Group(String name)
    {
        this.name = name;
        solvers = new ArrayList<>();
        fixtures = new TreeSet<>();
    }

    public void close()
    {
        for (Fixture fixture : fixtures)
        {
            fixture.close();
        }
    }

    public TreeSet<Fixture> GetFixtures()
    {
        return fixtures;
    }

    public String GetName()
    {
        return name;
    }

    public void Set(String attribute, float value)
    {
        solvers.stream().filter(solver -> solver.SolvesAttribute(attribute)).forEach(
            solver -> solver.Set(attribute, value)
        );
        for (Solver solver : solvers)
        {
            if (solver.SolvesAttribute(attribute))
            {
                solver.Set(attribute, value);
            }
        }
        fixtures
            .stream()
            .filter(fixture -> fixture.CanSet(attribute))
            .forEach(fixture -> fixture.Set(attribute, value));
    }

    @Override
    public String toString()
    {
        return GetName();
    }

    public Fixture FindFixture(String value)
    {
        for (Fixture fixture : fixtures)
        {
            if (fixture.toString().compareTo(value) == 0)
            {
                return fixture;
            }
        }
        return null;
    }

    public void SetName(String name)
    {
        this.name = name;
    }

    public void Update()
    {
        for (Fixture fixture : GetFixtures())
        {
            fixture.Update();
        }
        for (Solver solver : solvers)
        {
            solver.Solve();
        }
        for (Fixture fixture : GetFixtures())
        {
            fixture.UpdateDisplay();
        }


    }

    public ArrayList<Solver> GetSolvers()
    {
        return solvers;
    }

    public boolean HasSolver(String solverName)
    {
        for (Solver solver : solvers)
        {
            if (solver.GetType().equals(solverName))
            {
                return true;
            }
        }
        return false;
    }

    public Solver GetSolver(String solverType)
    {
        for (Solver solver : solvers)
        {
            if (solver.GetType().equals(solverType))
            {
                return solver;
            }
        }
        return null;
    }

    public void AddSimpleChaseSolver(int maxDistance)
    {
        solvers.add(new SimpleChaseSolver(this, maxDistance));
    }

    public void RemoveSolver(String solverType)
    {
        for (Solver solver : solvers)
        {
            if (solver.GetType().equals(solverType))
            {
                solvers.remove(solver);
                return;
            }
        }
    }

    public ArrayList<DMXFixture> GetDMXFixtures()
    {
        ArrayList<DMXFixture> dmxFixtures = new ArrayList<>();
        dmxFixtures.addAll(
            fixtures.stream()
                .filter(fixture -> fixture instanceof DMXFixture)
                .map(fixture -> (DMXFixture) fixture)
                .collect(Collectors.toList())
        );
        return dmxFixtures;
    }

    public ArrayList<PixelFixture> GetPixelFixtures()
    {
        ArrayList<PixelFixture> pixelFixtures = new ArrayList<>();
        pixelFixtures.addAll(
            fixtures.stream()
                .filter(fixture -> fixture instanceof PixelFixture)
                .map(fixture -> (PixelFixture) fixture)
                .collect(Collectors.toList())
        );
        return pixelFixtures;
    }
}
